/**
 * 
 */
package com.dhcc.cdbp.query;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * 通配符查询：
 * 	通配符来模糊查询，常见的通配符有?,*,-等等
 *   Luncene使用两个标准的通配符：*表示0个或多个字母，?表示0个或1个字母
 *   警告：当使用通配符进行查询时，可能会降低系统性能，较长的前缀（第一个通配符前面的字符）可以减少用于查找匹配搜枚举的项的个数。
 *   如果以通配符为首的查询模式会强制枚举所有索引中的项用于搜索匹配
 * @author 谢进军
 *
 */
public class WildcardQueryTest {

	private static final String fieldName = "contents";
	
	private static final String values = "Javaxsfsfe";
	
	private static String quertString = "?a?a*";  
	
	private Directory directory = null;
	@Before public void setUp() throws Exception {
		directory = new RAMDirectory();
		IndexWriterConfig iwc = new IndexWriterConfig(new StandardAnalyzer());
		iwc.setOpenMode(OpenMode.CREATE);
		IndexWriter writer = new IndexWriter(directory, iwc);
		Document document = new Document();
		document.add(new StringField(fieldName, values,Store.YES));
		writer.addDocument(document);
		writer.close();
	}
	@Test public void test() throws IOException {
		List<Document> result = new ArrayList<>();
		IndexReader reader = DirectoryReader.open(directory);
		assertEquals(1, reader.maxDoc());
		IndexSearcher searcher = new IndexSearcher(reader);
//		WildcardQuery构造函数除了需要一个Term对象以外，还有一个参数需要设置maxDeterminizedStates
//		其实就是设置根据通配符支持最大能支持有多少Term情况，Term越多占的硬盘空间越大，但查询也更精确。这个值默认源码里给定的是10000，默认即可。
//		Query query = new WildcardQuery( new Term(fieldName,quertString),1000);
		Query query = new WildcardQuery( new Term(fieldName,quertString));
		TopDocs docs = searcher.search(query, 10);
		ScoreDoc[] hits = docs.scoreDocs;
		for (ScoreDoc doc : hits) {
			int docId = doc.doc;
			Document document = searcher.doc(docId);
			result.add(document);
		}
		reader.close();
		for( Document document : result){
			System.out.println(document.get(fieldName));
		}
	}

	@After public void tearDown() throws Exception {
	}
}
